package com.ara.common.kernel.util;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Created by XieXin on 2018/12/10.
 * 文件管理
 */
public class FileUtils {
    private FileUtils() {
        // external storage  外部存储
        // Environment.getExternalStorageDirectory()	SD根目录:/mnt/sdcard/ (6.0后写入需要用户授权)
        // context.getExternalFilesDir(dir)	            路径为:/mnt/sdcard/Android/data/< package name >/files/… 
        // context.getExternalCacheDir()	            路径为:/mnt/sdcard//Android/data/< package name >/cach/…

        // internal storage  内部存储
        // context.getFilesDir()	    路径是:/data/data/< package name >/files/…
        // context.getCacheDir()	    路径是:/data/data/< package name >/cach/…
    }

    /**
     * 获取缓存路径
     *
     * @param context
     * @return
     */
    public static String getCacheDir(Context context) {
        if (context == null) return "";
        File file = context.getCacheDir();
        return file.getAbsolutePath() + File.separator;
    }

    /**
     * 获取缓存路径
     *
     * @param context
     * @return
     */
    public static String getCacheDir(Context context, String name) {
        if (context == null) return "";
        File file = new File(context.getCacheDir() + File.separator + name);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取APK缓存路径
     *
     * @param context
     * @return
     */
    public static String getApkCacheDir(Context context) {
        if (context == null) return "";
        File file = new File(context.getCacheDir() + File.separator + "apk");
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * 获取Pictures路径
     *
     * @param context
     * @return
     */
    public static String getPicturesDir(Context context) {
        if (context == null) return "";
        File file = new File(context.getCacheDir() + File.separator + Environment.DIRECTORY_PICTURES);
        if (!file.exists()) {
            file.mkdirs();
        }
        return file.getAbsolutePath();
    }

    /**
     * AndroidQ以上保存图片到公共目录
     * 公共目录下创建文件或文件夹拿到本地路径uri
     *
     * @param imageName    图片名称
     * @param imageType    图片类型
     * @param relativePath 缓存路径 包含某个媒体下的子路径
     */
    public static Uri insertImageFileIntoMediaStore(Context context, String imageName, String imageType,
                                                    String relativePath) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            return null;
        }
        if (TextUtils.isEmpty(relativePath)) {
            return null;
        }
        Uri insertUri = null;
        ContentResolver resolver = context.getContentResolver();

        //设置文件参数到ContentValues中
        ContentValues values = new ContentValues();
        //设置文件名
        values.put(MediaStore.Images.Media.DISPLAY_NAME, imageName);
        //设置文件描述，这里以文件名为例子
        values.put(MediaStore.Images.Media.DESCRIPTION, imageName);
        //设置文件类型为image/*
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/" + imageType);
        //注意：MediaStore.Images.Media.RELATIVE_PATH需要targetSdkVersion=29,
        //故该方法只可在Android10的手机上执行
        values.put(MediaStore.Images.Media.RELATIVE_PATH, relativePath);
        //EXTERNAL_CONTENT_URI代表外部存储器
        Uri external = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        //insertUri表示文件保存的uri路径
        insertUri = resolver.insert(external, values);
        return insertUri;
    }

    /**
     * 保存文件
     *
     * @param context    上下文
     * @param insertUri  文件保存的uri路径
     * @param sourcePath 来源、文件路径
     */
    public static void saveFile(Context context, Uri insertUri, String sourcePath) {
        if (insertUri == null) return;

        ContentResolver resolver = context.getContentResolver();

        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(sourcePath);
            outputStream = resolver.openOutputStream(insertUri);
            if (outputStream == null) return;

            byte[] fileReader = new byte[4096];
            while (true) {
                int read = inputStream.read(fileReader);
                if (read == -1) break;
                outputStream.write(fileReader, 0, read);
                outputStream.flush();
            }

        } catch (IOException e) {
            LoggerUtils.e(e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
        }
    }

    /**
     * 保存文件
     *
     * @param inputStream
     * @param path
     * @param filename
     */
    public static void writeFileToDisk(InputStream inputStream, String path, String filename) {
        OutputStream outputStream = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }

            File futureStudioIconFile = new File(path, filename);
            byte[] fileReader = new byte[4096];
            outputStream = new FileOutputStream(futureStudioIconFile);

            while (true) {
                int read = inputStream.read(fileReader);
                if (read == -1) break;
                outputStream.write(fileReader, 0, read);
            }
        } catch (IOException e) {
            LoggerUtils.e(e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
        }
    }

    /**
     * 保存文件
     *
     * @param dest
     * @param path
     * @param filename
     */
    public static void writeFileToDisk(File dest, String path, String filename) {
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            inputStream = new FileInputStream(dest);

            File futureStudioIconFile = new File(path, filename);
            byte[] fileReader = new byte[4096];
            outputStream = new FileOutputStream(futureStudioIconFile);

            while (true) {
                int read = inputStream.read(fileReader);
                if (read == -1) break;
                outputStream.write(fileReader, 0, read);
            }

        } catch (IOException e) {
            LoggerUtils.e(e.getMessage());
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
        }
    }


    /**
     * 保存文件
     *
     * @param bitmap
     * @param path
     * @param filename
     */
    public static void writeFileToDisk(Bitmap bitmap, String path, String filename) {
        OutputStream outputStream = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }

            File futureStudioIconFile = new File(path, filename);
            outputStream = new FileOutputStream(futureStudioIconFile);

            if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)) {
                outputStream.flush();
            }
        } catch (IOException e) {
            LoggerUtils.e(e.getMessage());
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
        }
    }

    /**
     * 保存字符串
     *
     * @param msg
     * @param path
     * @param filename
     */
    public static void writeStringToDisk(String msg, String path, String filename) {
        OutputStream outputStream = null;
        try {
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }

            File futureStudioIconFile = new File(path, filename);
            outputStream = new FileOutputStream(futureStudioIconFile);
            outputStream.write(msg.getBytes());
        } catch (IOException e) {
            LoggerUtils.e(e.getMessage());
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    LoggerUtils.e(e.getMessage());
                }
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param filePath 被删除文件的文件名
     * @return 文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String filePath) {
        File file = new File(filePath);
        if (file.isFile() && file.exists()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 删除单个文件
     *
     * @param file 被删除文件
     * @return 文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(File file) {
        if (file.isFile() && file.exists()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 删除文件夹以及目录下的文件
     *
     * @param filePath 被删除目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String filePath) {
        boolean flag = false;
        //如果filePath不以文件分隔符结尾，自动添加文件分隔符
        if (!filePath.endsWith(File.separator)) {
            filePath = filePath + File.separator;
        }
        File dirFile = new File(filePath);
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        flag = true;
        File[] files = dirFile.listFiles();
        if (files == null) return false;
        //遍历删除文件夹下的所有文件(包括子目录)
        for (File file : files) {
            if (file.isFile()) {
                //删除子文件
                flag = deleteFile(file.getAbsolutePath());
            } else {
                //删除子目录
                flag = deleteDirectory(file.getAbsolutePath());
            }
            if (!flag) break;
        }
        if (!flag) return false;
        //删除当前空目录
        return dirFile.delete();
    }
}
